Suggested citation: > Miranti, Ragdad Cani.(2020). Regional Poverty Convergence across Districts in Indonesia: A Distribution Dynamics Approach https://rpubs.com/canimiranti/distribution_dynamics_poverty514districts
This work is licensed under the Creative Commons Attribution-Non Commercial-Share Alike 4.0 International License.
Original data source
Data of Headcount Index (Poverty Rate) are derived from the Indonesia Central Bureau of Statistics (Badan Pusat Statistik Republik of Indonesia). https://www.bps.go.id/
Acknowledgment:
Material adapted from multiple sources, in particular from Magrini (2007).
Libraries
knitr::opts_chunk$set(echo = TRUE)
library(tidyverse)
library(skimr)
library(kableExtra) # html tables
library(pdfCluster) # density based clusters
library(hdrcde) # conditional density estimation
library(plotly)
library(intoo)
library(barsurf)
library(bivariate)
library(np)
library(quantreg)
library(basetheme)
basetheme("minimal")
library(viridis)
library(ggpointdensity)
library(isoband)
#library(MASS)
library(KernSmooth)
# Change the presentation of decimal numbers to 4 and avoid scientific notation
options(prompt="R> ", digits=4, scipen=7)
Tutorial objectives
Study the dynamics of univariate densities
Compute the bandwidth of a density
Study mobility plots
Study bi-variate densities
Study density-based clustering methods
Study conditional bi-variate densities
Import data
dat <- read_csv("poverty.csv")
dat <- as.data.frame(dat)
Descriptive statistics
── Data Summary ────────────────────────
Values
Name dat
Number of rows 514
Number of columns 13
_______________________
Column type frequency:
character 1
numeric 12
________________________
Group variables None
── Variable type: character ────────────────────────────────────────────────────────────
skim_variable n_missing complete_rate min max empty n_unique whitespace
1 District 0 1 4 26 0 514 0
── Variable type: numeric ──────────────────────────────────────────────────────────────
skim_variable n_missing complete_rate mean sd p0 p25 p50
1 Code 0 1 4558. 2678. 911 1803. 3550
2 pov2010 0 1 15.6 9.42 1.67 9.01 13.3
3 pov2011 0 1 14.6 8.92 1.5 8.14 12.4
4 pov2012 0 1 13.9 8.55 1.33 7.79 11.8
5 pov2013 0 1 13.8 8.59 1.75 7.76 11.7
6 pov2014 0 1 13.1 7.93 1.68 7.38 11.2
7 pov2015 0 1 13.5 8.25 1.69 7.59 11.6
8 pov2016 0 1 13.2 8.20 1.67 7.40 11.2
9 pov2017 0 1 13.0 7.98 1.76 7.35 11.1
10 pov2018 0 1 12.3 7.84 1.68 6.99 10.2
11 rel_pov2010 0 1 1 0.603 0.107 0.577 0.854
12 rel_pov2018 0 1 1.27 0.763 0.135 0.730 1.08
p75 p100 hist
1 7174. 9471 ▇▆▂▇▃
2 19.6 49.6 ▇▇▂▁▁
3 18.9 47.4 ▇▇▂▁▁
4 17.8 45.9 ▇▇▂▁▁
5 17.4 47.5 ▇▆▂▁▁
6 16.6 44.5 ▇▆▂▁▁
7 16.9 45.7 ▇▇▂▁▁
8 16.3 45.1 ▇▇▂▁▁
9 16.0 43.6 ▇▇▂▁▁
10 15.1 43.5 ▇▆▂▁▁
11 1.25 3.18 ▇▇▂▁▁
12 1.59 4.02 ▇▇▂▁▁
xy <- dat %>%
select(
pov2010,
pov2018,
) %>%
mutate(
x = pov2010,
y = pov2018
) %>%
select(
x,
y
)
Univariate dynamics
Select bandwiths
Select bandwidth based on function dpik from the package KernSmooth
h_rel_pov2010<- dpik(dat$rel_pov2010)
h_rel_pov2010
[1] 0.1026
h_rel_pov2018 <- dpik(dat$rel_pov2018)
h_rel_pov2018
[1] 0.1299
Plot each density
dis_rel_pov2010 <- bkde(dat$rel_pov2010, bandwidth = h_rel_pov2010)
dis_rel_pov2010 <- as.data.frame(dis_rel_pov2010)
ggplot(dis_rel_pov2010, aes(x, y)) + geom_line() +
theme_minimal()

dis_rel_pov2018 <- bkde(dat$rel_pov2018, bandwidth = h_rel_pov2018)
dis_rel_pov2018 <- as.data.frame(dis_rel_pov2018)
ggplot(dis_rel_pov2018, aes(x, y)) + geom_line() +
theme_minimal()

Plot both densities
There are two methods for plot both densities,i.e. Kernsmooth and bandwith default of ggplot. I prefer using the gglot ( Method 2).
Method 2 (ggplot)
Using the bandwidth default of ggplot Manual labels are not yet implemented in the ggplotly function
rel_pov2010 <- dat %>%
select(rel_pov2010) %>%
rename(rel_var = rel_pov2010) %>%
mutate(year = 2010)
rel_pov2018 <- dat %>%
select(rel_pov2018) %>%
rename(rel_var = rel_pov2018) %>%
mutate(year = 2018)
rel_pov2010pov2018 <- bind_rows(rel_pov2010, rel_pov2018)
rel_pov2010pov2018 <- rel_pov2010pov2018 %>%
mutate(year = as.factor(year))
head(rel_pov2010pov2018)
dis_rel_pov2010pov2018 <- ggplot(rel_pov2010pov2018,aes(x=rel_var, color=year)) +
geom_density() +
theme_minimal()
dis_rel_pov2010pov2018

Using plotly
ggplotly(dis_rel_pov2010pov2018)
Bivariate density
Using Mobility scatterplot
dat %>%
ggplot(aes(x = rel_pov2010, y = rel_pov2018)) +
geom_point(alpha=0.5) +
geom_abline(aes(intercept = 0, slope = 1)) +
geom_hline(yintercept = 1, linetype="dashed") +
geom_vline(xintercept = 1, linetype="dashed") +
theme_minimal() +
labs(subtitle = "Relative Pov2018",
x = "Relative Pov2010",
y = "") +
theme(text=element_text(family="Palatino"))

Fit a non-linear function
dat %>%
ggplot(aes(x = rel_pov2010, y = rel_pov2018)) +
geom_point(alpha=0.5) +
geom_smooth() +
geom_abline(aes(intercept = 0, slope = 1)) +
geom_hline(yintercept = 1, linetype="dashed") +
geom_vline(xintercept = 1, linetype="dashed") +
theme_minimal() +
labs(subtitle = "Relative pov2018",
x = "Relative pov2010",
y = "") +
theme(text=element_text(family="Palatino"))

Not that the nonlinear fit crosses the 45-degree line two times from above.
Using the Bivariate package
bivariate <- kbvpdf(dat$rel_pov2010, dat$rel_pov2018, h_rel_pov2010, h_rel_pov2018)
plot(bivariate,
xlab="Relative Poverty 2010",
ylab="Relative Poverty 2018")
abline(a=0, b=1)

plot(bivariate,
TRUE,
xlab="Relative Poverty 2010",
ylab="Relative Poverty 2018")

Using ggplot (stat_density_2d)
dat %>%
ggplot(aes(x = rel_pov2010, y = rel_pov2018)) +
geom_point(color = "lightgray") +
geom_smooth() +
#geom_smooth(method=lm, se=FALSE) +
stat_density_2d() +
geom_abline(aes(intercept = 0, slope = 1)) +
geom_hline(yintercept = 1, linetype="dashed") +
geom_vline(xintercept = 1, linetype="dashed") +
theme_minimal() +
labs(subtitle = "Relative pov2018",
x = "Relative pov2010",
y = "") +
theme(text=element_text(family="Palatino"))

dat %>%
ggplot(aes(x = rel_pov2010, y = rel_pov2018)) +
stat_density_2d(aes(fill = stat(nlevel)), geom = "polygon") +
scale_fill_viridis_c() +
geom_abline(aes(intercept = 0, slope = 1)) +
geom_hline(yintercept = 1, linetype="dashed") +
geom_vline(xintercept = 1, linetype="dashed") +
theme_minimal() +
labs(x = "Relative Poverty Rate 2010",
y = "Relative Poverty Rate 2018") +
theme(text=element_text(size=8, family="Palatino"))

Using Stochastic Kernel Package
There are two ways of analyzing the use of stochastic kernel package: 1. Contour Plots and 2. Surface Plots
Contour Plots
pov2010pov2018 <- cbind(dat$rel_pov2010, dat$rel_pov2018)
pov2010pov2018_dis <- bkde2D(pov2010pov2018, bandwidth = c(h_rel_pov2010, h_rel_pov2018))
contour(pov2010pov2018_dis$x1,pov2010pov2018_dis$x2,pov2010pov2018_dis$fhat)
abline(a=0, b=1)

Surface Plots
plot_ly(x=pov2010pov2018_dis$x1, y=pov2010pov2018_dis$x2, z=pov2010pov2018_dis$fhat) %>% add_surface()
plot_ly(x=pov2010pov2018_dis$x1, y=pov2010pov2018_dis$x2, z=pov2010pov2018_dis$fhat, type = "contour", contours = list(showlabels = TRUE)) %>%
colorbar(title = "Density")
Conditional density analysis
Using the hdrcde package
pov2010pov2018_cde <- cde(dat$pov2010, dat$pov2018)
Increase the number of intervals to 20
pov2010pov2018_cde2 <- cde(dat$pov2010, dat$pov2018, nxmargin = 20)

plot(pov2010pov2018_cde2)

High density regions
plot(pov2010pov2018_cde, plot.fn="hdr")
abline(a=0, b=1)

References
Magrini, S. (2007). Analysing convergence through the distribution dynamics approach: why and how?. University Ca’Foscari of Venice, Dept. of Economics Research Paper Series No, 13.
Mendez C. (2020). Classical sigma and beta convergence analysis in R: Using the REAT 2.1 Package. R Studio/RPubs. Available at https://rpubs.com/quarcs-lab/classical-convergence-reat21
Mendez C. (2020). Univariate distribution dynamics in R: Using the ggridges package. R Studio/RPubs. Available at https://rpubs.com/quarcs-lab/univariate-distribution-dynamics
Mendez, C. (2020) Regional efficiency convergence and efficiency clusters. Asia-Pacific Journal of Regional Science, 1-21.
Mendez, C. (2019). Lack of Global Convergence and the Formation of Multiple Welfare Clubs across Countries: An Unsupervised Machine Learning Approach. Economies, 7(3), 74.
Mendez, C. (2019). Overall efficiency, pure technical efficiency, and scale efficiency across provinces in Indonesia 1990 and 2010. R Studio/RPubs. Available at https://rpubs.com/quarcs-lab/efficiency-clusters-indonesia-1990-2010
Mendez-Guerra, C. (2018). On the distribution dynamics of human development: Evidence from the metropolitan regions of Bolivia’’. Economics Bulletin, 38(4), 2467-2475.
END
LS0tCnRpdGxlOiAiUmVnaW9uYWwgUG92ZXJ0eSBDb252ZXJnZW5jZSBhY3Jvc3MgRGlzdHJpY3RzIGluIEluZG9uZXNpYTpBIERpc3RyaWJ1dGlvbiBEeW5hbWljcyBBcHByb2FjaCIKYXV0aG9yOiAiUmFnZGFkIENhbmkgTWlyYW50aSIKb3V0cHV0OiAKICBnaXRodWJfZG9jdW1lbnQ6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiBmYWxzZQogICAgdG9jX2RlcHRoOiA0CiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIGNvZGVfZm9sZGluZzogInNob3ciCiAgICB0aGVtZTogImNvc21vIgogICAgaGlnaGxpZ2h0OiAibW9ub2Nocm9tZSIKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKICB3b3JkX2RvY3VtZW50OiBkZWZhdWx0CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgICB0b2NfZGVwdGg6IDQKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgY29kZV9mb2xkaW5nOiAiaGlkZSIKICAgIHRoZW1lOiAiY29zbW8iCiAgICBoaWdobGlnaHQ6ICJtb25vY2hyb21lIgogICAgZGZfcHJpbnQ6ICJrYWJsZSIKLS0tCgo8c3R5bGU+CmgxLnRpdGxlIHtmb250LXNpemU6IDE4cHQ7IGNvbG9yOiBEYXJrQmx1ZTt9IApib2R5LCBoMSwgaDIsIGgzLCBoNCB7Zm9udC1mYW1pbHk6ICJQYWxhdGlubyIsIHNlcmlmO30KYm9keSB7Zm9udC1zaXplOiAxMnB0O30KLyogSGVhZGVycyAqLwpoMSxoMixoMyxoNCxoNSxoNntmb250LXNpemU6IDE0cHQ7IGNvbG9yOiAjMDAwMDhCO30KYm9keSB7Y29sb3I6ICMzMzMzMzM7fQphLCBhOmhvdmVyIHtjb2xvcjogIzhCM0E2Mjt9CnByZSB7Zm9udC1zaXplOiAxMnB4O30KPC9zdHlsZT4KClN1Z2dlc3RlZCBjaXRhdGlvbjogCj4gTWlyYW50aSwgUmFnZGFkIENhbmkuKDIwMjApLiBSZWdpb25hbCBQb3ZlcnR5IENvbnZlcmdlbmNlIGFjcm9zcyBEaXN0cmljdHMgaW4gSW5kb25lc2lhOiBBIERpc3RyaWJ1dGlvbiBEeW5hbWljcyBBcHByb2FjaCA8aHR0cHM6Ly9ycHVicy5jb20vY2FuaW1pcmFudGkvZGlzdHJpYnV0aW9uX2R5bmFtaWNzX3BvdmVydHk1MTRkaXN0cmljdHM+CgoKVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uLU5vbiBDb21tZXJjaWFsLVNoYXJlIEFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIAoKIyBPcmlnaW5hbCBkYXRhIHNvdXJjZQoKRGF0YSBvZiBIZWFkY291bnQgSW5kZXggKFBvdmVydHkgUmF0ZSkgYXJlIGRlcml2ZWQgZnJvbSB0aGUgSW5kb25lc2lhIENlbnRyYWwgQnVyZWF1IG9mIFN0YXRpc3RpY3MgKEJhZGFuIFB1c2F0IFN0YXRpc3RpayBSZXB1YmxpayBvZiBJbmRvbmVzaWEpLiA8aHR0cHM6Ly93d3cuYnBzLmdvLmlkLz4KCkFja25vd2xlZGdtZW50OgoKTWF0ZXJpYWwgYWRhcHRlZCBmcm9tIG11bHRpcGxlIHNvdXJjZXMsIGluIHBhcnRpY3VsYXIgZnJvbSBbTWFncmluaSAoMjAwNykuXShodHRwczovL3BkZnMuc2VtYW50aWNzY2hvbGFyLm9yZy9lYWIxL2NiODlkZGUwYzkwOTg5OGIwYTQzMjczMzc3YzVkZmE3M2ViYy5wZGYpCgojIExpYnJhcmllcwoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQoKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc2tpbXIpCmxpYnJhcnkoa2FibGVFeHRyYSkgICAgIyBodG1sIHRhYmxlcyAKbGlicmFyeShwZGZDbHVzdGVyKSAgICAjIGRlbnNpdHkgYmFzZWQgY2x1c3RlcnMKbGlicmFyeShoZHJjZGUpICAgICAgICAjIGNvbmRpdGlvbmFsIGRlbnNpdHkgZXN0aW1hdGlvbiAKbGlicmFyeShwbG90bHkpCgpsaWJyYXJ5KGludG9vKQpsaWJyYXJ5KGJhcnN1cmYpCmxpYnJhcnkoYml2YXJpYXRlKQoKbGlicmFyeShucCkKbGlicmFyeShxdWFudHJlZykKCmxpYnJhcnkoYmFzZXRoZW1lKQpiYXNldGhlbWUoIm1pbmltYWwiKQoKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGdncG9pbnRkZW5zaXR5KQpsaWJyYXJ5KGlzb2JhbmQpCgojbGlicmFyeShNQVNTKQpsaWJyYXJ5KEtlcm5TbW9vdGgpCgoKIyBDaGFuZ2UgdGhlIHByZXNlbnRhdGlvbiBvZiBkZWNpbWFsIG51bWJlcnMgdG8gNCBhbmQgYXZvaWQgc2NpZW50aWZpYyBub3RhdGlvbgpvcHRpb25zKHByb21wdD0iUj4gIiwgZGlnaXRzPTQsIHNjaXBlbj03KQoKYGBgCgojIFR1dG9yaWFsIG9iamVjdGl2ZXMKCi0gU3R1ZHkgdGhlIGR5bmFtaWNzIG9mIHVuaXZhcmlhdGUgZGVuc2l0aWVzCgotIENvbXB1dGUgdGhlIGJhbmR3aWR0aCBvZiBhIGRlbnNpdHkKCi0gU3R1ZHkgbW9iaWxpdHkgcGxvdHMKCi0gU3R1ZHkgYmktdmFyaWF0ZSBkZW5zaXRpZXMKCi0gU3R1ZHkgZGVuc2l0eS1iYXNlZCBjbHVzdGVyaW5nIG1ldGhvZHMKCi0gU3R1ZHkgY29uZGl0aW9uYWwgYmktdmFyaWF0ZSBkZW5zaXRpZXMKCgoKIyBJbXBvcnQgZGF0YQoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1UUlVFfQpkYXQgPC0gcmVhZF9jc3YoInBvdmVydHkuY3N2IikKZGF0IDwtIGFzLmRhdGEuZnJhbWUoZGF0KQpgYGAKCgojIFRyYW5zZm9ybSBkYXRhCgoKU2luY2UgdGhlIGRhdGEgaXMgaW4gcmVsYXRpdmUgdGVybXMsIGxldCB1cyByZW5hbWUgdGhlIHZhcmlhYmxlcyBhbmQgYWRkIG5ldyB2YXJpYWJsZXMuCgoKYGBge3J9CmRhdCA8LSBkYXQgJT4lIAogIG11dGF0ZSgKICAgIHJlbF9wb3YyMDEwID0gcG92MjAxMC9tZWFuKHBvdjIwMTApLAogICAgcmVsX3BvdjIwMTggPSBwb3YyMDEwL21lYW4ocG92MjAxOCkKICApCmRhdApgYGAKCgoKIyBEZXNjcmlwdGl2ZSBzdGF0aXN0aWNzCgpgYGB7cn0Kc2tpbShkYXQpCmBgYAoKCmBgYHtyfQp4eSA8LSBkYXQgJT4lIApzZWxlY3QoCnBvdjIwMTAsCnBvdjIwMTgsCiAgKSAlPiUgCiAgbXV0YXRlKAogICAgeCA9IHBvdjIwMTAsCiAgICB5ID0gcG92MjAxOAogICkgJT4lIAogIHNlbGVjdCgKICAgIHgsCiAgICB5CiAgKQoKYGBgCgoKIyBVbml2YXJpYXRlIGR5bmFtaWNzCgojIyBTZWxlY3QgYmFuZHdpdGhzCgpTZWxlY3QgYmFuZHdpZHRoIGJhc2VkIG9uIGZ1bmN0aW9uIGBkcGlrYCBmcm9tIHRoZSBwYWNrYWdlIGBLZXJuU21vb3RoYAoKYGBge3J9CmhfcmVsX3BvdjIwMTA8LSBkcGlrKGRhdCRyZWxfcG92MjAxMCkKaF9yZWxfcG92MjAxMApgYGAKCgpgYGB7cn0KaF9yZWxfcG92MjAxOCA8LSBkcGlrKGRhdCRyZWxfcG92MjAxOCkKaF9yZWxfcG92MjAxOApgYGAKCiMjIFBsb3QgZWFjaCBkZW5zaXR5CgpgYGB7cn0KZGlzX3JlbF9wb3YyMDEwIDwtIGJrZGUoZGF0JHJlbF9wb3YyMDEwLCBiYW5kd2lkdGggPSBoX3JlbF9wb3YyMDEwKQpkaXNfcmVsX3BvdjIwMTAgPC0gYXMuZGF0YS5mcmFtZShkaXNfcmVsX3BvdjIwMTApCmdncGxvdChkaXNfcmVsX3BvdjIwMTAsIGFlcyh4LCB5KSkgKyBnZW9tX2xpbmUoKSArIAogIHRoZW1lX21pbmltYWwoKSAKYGBgCgoKYGBge3J9CmRpc19yZWxfcG92MjAxOCA8LSBia2RlKGRhdCRyZWxfcG92MjAxOCwgYmFuZHdpZHRoID0gaF9yZWxfcG92MjAxOCkKZGlzX3JlbF9wb3YyMDE4IDwtIGFzLmRhdGEuZnJhbWUoZGlzX3JlbF9wb3YyMDE4KQpnZ3Bsb3QoZGlzX3JlbF9wb3YyMDE4LCBhZXMoeCwgeSkpICsgZ2VvbV9saW5lKCkgKyAKICB0aGVtZV9taW5pbWFsKCkgCmBgYAoKCiMjIFBsb3QgYm90aCBkZW5zaXRpZXMKClRoZXJlIGFyZSB0d28gbWV0aG9kcyBmb3IgcGxvdCBib3RoIGRlbnNpdGllcyxpLmUuIEtlcm5zbW9vdGggYW5kIGJhbmR3aXRoIGRlZmF1bHQgb2YgZ2dwbG90LiBJIHByZWZlciB1c2luZyB0aGUgZ2dsb3QgKCBNZXRob2QgMikuCgojIE1ldGhvZCAyIChnZ3Bsb3QpCgpVc2luZyB0aGUgYmFuZHdpZHRoIGRlZmF1bHQgb2YgZ2dwbG90IApNYW51YWwgbGFiZWxzIGFyZSBub3QgeWV0IGltcGxlbWVudGVkIGluIHRoZSBgZ2dwbG90bHlgIGZ1bmN0aW9uCgpgYGB7cn0KcmVsX3BvdjIwMTAgPC0gZGF0ICU+JSAKICBzZWxlY3QocmVsX3BvdjIwMTApICU+JSAKICByZW5hbWUocmVsX3ZhciA9IHJlbF9wb3YyMDEwKSAlPiUgCiAgbXV0YXRlKHllYXIgPSAyMDEwKQpgYGAKCmBgYHtyfQpyZWxfcG92MjAxOCA8LSBkYXQgJT4lIAogIHNlbGVjdChyZWxfcG92MjAxOCkgJT4lIAogIHJlbmFtZShyZWxfdmFyID0gcmVsX3BvdjIwMTgpICU+JSAKICBtdXRhdGUoeWVhciA9IDIwMTgpCmBgYAoKYGBge3J9CnJlbF9wb3YyMDEwcG92MjAxOCA8LSBiaW5kX3Jvd3MocmVsX3BvdjIwMTAsIHJlbF9wb3YyMDE4KQpgYGAKIApgYGB7cn0KcmVsX3BvdjIwMTBwb3YyMDE4IDwtIHJlbF9wb3YyMDEwcG92MjAxOCAlPiUgCiAgbXV0YXRlKHllYXIgPSBhcy5mYWN0b3IoeWVhcikpCmhlYWQocmVsX3BvdjIwMTBwb3YyMDE4KQpgYGAKIAogCgpgYGB7cn0KZGlzX3JlbF9wb3YyMDEwcG92MjAxOCA8LSBnZ3Bsb3QocmVsX3BvdjIwMTBwb3YyMDE4LGFlcyh4PXJlbF92YXIsIGNvbG9yPXllYXIpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKyAKICB0aGVtZV9taW5pbWFsKCkgCmRpc19yZWxfcG92MjAxMHBvdjIwMTgKYGBgCgoKVXNpbmcgcGxvdGx5CgpgYGB7cn0KZ2dwbG90bHkoZGlzX3JlbF9wb3YyMDEwcG92MjAxOCkKYGBgCgoKCiMgQml2YXJpYXRlIGRlbnNpdHkKCiMjIFVzaW5nIE1vYmlsaXR5IHNjYXR0ZXJwbG90CgpgYGB7cn0KZGF0ICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWxfcG92MjAxMCwgeSA9IHJlbF9wb3YyMDE4KSkgKwogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArCiAgZ2VvbV9hYmxpbmUoYWVzKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZT0iZGFzaGVkIikgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyhzdWJ0aXRsZSA9ICJSZWxhdGl2ZSBQb3YyMDE4IiwKICAgICAgIHggPSAiUmVsYXRpdmUgUG92MjAxMCIsCiAgICAgICB5ID0gIiIpICsKICB0aGVtZSh0ZXh0PWVsZW1lbnRfdGV4dChmYW1pbHk9IlBhbGF0aW5vIikpIApgYGAKCgpGaXQgYSBub24tbGluZWFyIGZ1bmN0aW9uCgpgYGB7cn0KZGF0ICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWxfcG92MjAxMCwgeSA9IHJlbF9wb3YyMDE4KSkgKwogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArIAogIGdlb21fc21vb3RoKCkgKyAKICBnZW9tX2FibGluZShhZXMoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGxpbmV0eXBlPSJkYXNoZWQiKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGxpbmV0eXBlPSJkYXNoZWQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHN1YnRpdGxlID0gIlJlbGF0aXZlIHBvdjIwMTgiLAogICAgICAgeCA9ICJSZWxhdGl2ZSBwb3YyMDEwIiwKICAgICAgIHkgPSAiIikgKwogIHRoZW1lKHRleHQ9ZWxlbWVudF90ZXh0KGZhbWlseT0iUGFsYXRpbm8iKSkgCmBgYAoKTm90IHRoYXQgdGhlIG5vbmxpbmVhciBmaXQgY3Jvc3NlcyB0aGUgNDUtZGVncmVlIGxpbmUgdHdvIHRpbWVzIGZyb20gYWJvdmUuCgojIyBVc2luZyB0aGUgQml2YXJpYXRlIHBhY2thZ2UKCmBgYHtyfQpiaXZhcmlhdGUgPC0ga2J2cGRmKGRhdCRyZWxfcG92MjAxMCwgZGF0JHJlbF9wb3YyMDE4LCBoX3JlbF9wb3YyMDEwLCBoX3JlbF9wb3YyMDE4KSAKYGBgCgoKYGBge3J9CnBsb3QoYml2YXJpYXRlLAogICAgICB4bGFiPSJSZWxhdGl2ZSBQb3ZlcnR5IDIwMTAiLCAKICAgICAgeWxhYj0iUmVsYXRpdmUgUG92ZXJ0eSAyMDE4IikKYWJsaW5lKGE9MCwgYj0xKQphYmxpbmUoaD0xLCB2PTEpCmBgYAoKCmBgYHtyfQpwbG90KGJpdmFyaWF0ZSwKICAgICAgVFJVRSwKICAgICAgeGxhYj0iUmVsYXRpdmUgUG92ZXJ0eSAyMDEwIiwgCiAgICAgIHlsYWI9IlJlbGF0aXZlIFBvdmVydHkgMjAxOCIpCmBgYAoKCiMjIFVzaW5nIGdncGxvdCAoc3RhdF9kZW5zaXR5XzJkKQoKYGBge3J9CmRhdCAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gcmVsX3BvdjIwMTAsIHkgPSByZWxfcG92MjAxOCkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gImxpZ2h0Z3JheSIpICsgCiAgZ2VvbV9zbW9vdGgoKSArIAogICNnZW9tX3Ntb290aChtZXRob2Q9bG0sIHNlPUZBTFNFKSArIAogIHN0YXRfZGVuc2l0eV8yZCgpICsKICBnZW9tX2FibGluZShhZXMoaW50ZXJjZXB0ID0gMCwgc2xvcGUgPSAxKSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGxpbmV0eXBlPSJkYXNoZWQiKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsIGxpbmV0eXBlPSJkYXNoZWQiKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHN1YnRpdGxlID0gIlJlbGF0aXZlIHBvdjIwMTgiLAogICAgICAgeCA9ICJSZWxhdGl2ZSBwb3YyMDEwIiwKICAgICAgIHkgPSAiIikgKwogIHRoZW1lKHRleHQ9ZWxlbWVudF90ZXh0KGZhbWlseT0iUGFsYXRpbm8iKSkgCmBgYAoKCgpgYGB7cn0KZGF0ICU+JSAKICBnZ3Bsb3QoYWVzKHggPSByZWxfcG92MjAxMCwgeSA9IHJlbF9wb3YyMDE4KSkgKwogICAgICAgIHN0YXRfZGVuc2l0eV8yZChhZXMoZmlsbCA9IHN0YXQobmxldmVsKSksIGdlb20gPSAicG9seWdvbiIpICsgCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MoKSArCiAgICAgICAgZ2VvbV9hYmxpbmUoYWVzKGludGVyY2VwdCA9IDAsIHNsb3BlID0gMSkpICsKICAgICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZT0iZGFzaGVkIikgKyAKICAgICAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZT0iZGFzaGVkIikgKyAKICB0aGVtZV9taW5pbWFsKCkgKwogICAgICAgIGxhYnMoeCA9ICJSZWxhdGl2ZSBQb3ZlcnR5IFJhdGUgMjAxMCIsCiAgICAgICAgICAgICB5ID0gIlJlbGF0aXZlIFBvdmVydHkgUmF0ZSAyMDE4IikgKwogICAgICAgIHRoZW1lKHRleHQ9ZWxlbWVudF90ZXh0KHNpemU9OCwgZmFtaWx5PSJQYWxhdGlubyIpKQpgYGAKCgojIyBVc2luZyBTdG9jaGFzdGljIEtlcm5lbCBQYWNrYWdlCgpUaGVyZSBhcmUgdHdvIHdheXMgb2YgYW5hbHl6aW5nIHRoZSB1c2Ugb2Ygc3RvY2hhc3RpYyBrZXJuZWwgcGFja2FnZTogMS4gQ29udG91ciBQbG90cwphbmQgMi4gU3VyZmFjZSBQbG90cwoKIyMjIENvbnRvdXIgUGxvdHMKCmBgYHtyfQpwb3YyMDEwcG92MjAxOCA8LSBjYmluZChkYXQkcmVsX3BvdjIwMTAsIGRhdCRyZWxfcG92MjAxOCkKcG92MjAxMHBvdjIwMThfZGlzIDwtIGJrZGUyRChwb3YyMDEwcG92MjAxOCwgYmFuZHdpZHRoID0gYyhoX3JlbF9wb3YyMDEwLCBoX3JlbF9wb3YyMDE4KSkgCmBgYAoKYGBge3J9CmNvbnRvdXIocG92MjAxMHBvdjIwMThfZGlzJHgxLHBvdjIwMTBwb3YyMDE4X2RpcyR4Mixwb3YyMDEwcG92MjAxOF9kaXMkZmhhdCkKYWJsaW5lKGE9MCwgYj0xKQpgYGAKCiMjIyBTdXJmYWNlIFBsb3RzCgpgYGB7cn0KcGxvdF9seSh4PXBvdjIwMTBwb3YyMDE4X2RpcyR4MSwgeT1wb3YyMDEwcG92MjAxOF9kaXMkeDIsIHo9cG92MjAxMHBvdjIwMThfZGlzJGZoYXQpICU+JSBhZGRfc3VyZmFjZSgpCmBgYApgYGB7cn0KcGxvdF9seSh4PXBvdjIwMTBwb3YyMDE4X2RpcyR4MSwgeT1wb3YyMDEwcG92MjAxOF9kaXMkeDIsIHo9cG92MjAxMHBvdjIwMThfZGlzJGZoYXQsIHR5cGUgPSAiY29udG91ciIsIGNvbnRvdXJzID0gbGlzdChzaG93bGFiZWxzID0gVFJVRSkpICAlPiUKICBjb2xvcmJhcih0aXRsZSA9ICJEZW5zaXR5IikKYGBgCgojIENvbmRpdGlvbmFsIGRlbnNpdHkgYW5hbHlzaXMKCiMjIFVzaW5nIHRoZSBgaGRyY2RlYCBwYWNrYWdlCgpgYGB7cn0KcG92MjAxMHBvdjIwMThfY2RlIDwtIGNkZShkYXQkcG92MjAxMCwgZGF0JHBvdjIwMTgpCmBgYAoKSW5jcmVhc2UgdGhlIG51bWJlciBvZiBpbnRlcnZhbHMgdG8gMjAKCmBgYHtyfQpwb3YyMDEwcG92MjAxOF9jZGUyIDwtIGNkZShkYXQkcG92MjAxMCwgZGF0JHBvdjIwMTgsIG54bWFyZ2luID0gMjApCmBgYAoKCmBgYHtyfQpwbG90KHBvdjIwMTBwb3YyMDE4X2NkZSkKYGBgCgoKYGBge3J9CnBsb3QocG92MjAxMHBvdjIwMThfY2RlMikKYGBgCgoKSGlnaCBkZW5zaXR5IHJlZ2lvbnMKCgpgYGB7cn0KcGxvdChwb3YyMDEwcG92MjAxOF9jZGUsIHBsb3QuZm49ImhkciIpCmFibGluZShhPTAsIGI9MSkKYWJsaW5lKGg9MSwgdj0xKQpgYGAKCgojIFJlZmVyZW5jZXMKCi0gW01hZ3JpbmksIFMuICgyMDA3KS4gQW5hbHlzaW5nIGNvbnZlcmdlbmNlIHRocm91Z2ggdGhlIGRpc3RyaWJ1dGlvbiBkeW5hbWljcyBhcHByb2FjaDogd2h5IGFuZCBob3c/LiBVbml2ZXJzaXR5IENhJ0Zvc2Nhcmkgb2YgVmVuaWNlLCBEZXB0LiBvZiBFY29ub21pY3MgUmVzZWFyY2ggUGFwZXIgU2VyaWVzIE5vLCAxMy4gXShodHRwczovL3BkZnMuc2VtYW50aWNzY2hvbGFyLm9yZy9lYWIxL2NiODlkZGUwYzkwOTg5OGIwYTQzMjczMzc3YzVkZmE3M2ViYy5wZGYpCgotIE1lbmRleiBDLiAoMjAyMCkuIENsYXNzaWNhbCBzaWdtYSBhbmQgYmV0YSBjb252ZXJnZW5jZSBhbmFseXNpcyBpbiBSOiBVc2luZyB0aGUgUkVBVCAyLjEgUGFja2FnZS4gUiBTdHVkaW8vUlB1YnMuIEF2YWlsYWJsZSBhdCBodHRwczovL3JwdWJzLmNvbS9xdWFyY3MtbGFiL2NsYXNzaWNhbC1jb252ZXJnZW5jZS1yZWF0MjEKCi0gTWVuZGV6IEMuICgyMDIwKS4gVW5pdmFyaWF0ZSBkaXN0cmlidXRpb24gZHluYW1pY3MgaW4gUjogVXNpbmcgdGhlIGdncmlkZ2VzIHBhY2thZ2UuIFIgU3R1ZGlvL1JQdWJzLiBBdmFpbGFibGUgYXQgaHR0cHM6Ly9ycHVicy5jb20vcXVhcmNzLWxhYi91bml2YXJpYXRlLWRpc3RyaWJ1dGlvbi1keW5hbWljcwoKLSBbTWVuZGV6LCBDLiAoMjAyMCkgUmVnaW9uYWwgZWZmaWNpZW5jeSBjb252ZXJnZW5jZSBhbmQgZWZmaWNpZW5jeSBjbHVzdGVycy4gQXNpYS1QYWNpZmljIEpvdXJuYWwgb2YgUmVnaW9uYWwgU2NpZW5jZSwgMS0yMS5dKGh0dHA6Ly9lbS5yZGN1LmJlL3dmL2NsaWNrP3Vwbj1sTVp5MWxlcm5TSjdhcGM1RGdZTThZVGhTSTViS1cwNnpuVzNCYW5PLTJGUnMtM0RfdTZhMlBxRjN2c2xOTnRTUmJoeEpQY0pLeE81RUt6T3NmMC0yRldpaXpONTdkNGNzRjdSZU11cjVlNDBUYlg0OERiU2U5a0VNQ3dGcHZ2RnBMY3VhVkItMkJwZEMzZkxDYnNQMGlLY3N4SXMxZHYxeXJQc0dEQ05oNWJoZ3ZJOC0yRi0yQnh3ejd1cGpEZ3ljcVBiaE9iTnFrVDQxdXFZM2RQaVhyNXZCb1kxeHdUODhNQTMtMkZiZEpnd29CbDFHbnpsaTEzbWttbEpqMGtxVHMtMkJsbFZmQ1RCMzU2bUxqaktSMlZCWkNVZ0tieVZwWWd1MXZYandUd2RPeXpkNUZUYlU4ZWFSc1d5T1JqZTdXQ1BwR0VLQ1VBdmJlVENTUGEycmZka21ua1FJcnNtWUJTcWZTWjhhYVd6SHdJa01VM2h4YklVNm5IR1EpIAoKLSBbTWVuZGV6LCBDLiAoMjAxOSkuIExhY2sgb2YgR2xvYmFsIENvbnZlcmdlbmNlIGFuZCB0aGUgRm9ybWF0aW9uIG9mIE11bHRpcGxlIFdlbGZhcmUgQ2x1YnMgYWNyb3NzIENvdW50cmllczogQW4gVW5zdXBlcnZpc2VkIE1hY2hpbmUgTGVhcm5pbmcgQXBwcm9hY2guIEVjb25vbWllcywgNygzKSwgNzQuXShodHRwczovL3d3dy5tZHBpLmNvbS8yMjI3LTcwOTkvNy8zLzc0L3BkZikKCi0gTWVuZGV6LCBDLiAoMjAxOSkuIE92ZXJhbGwgZWZmaWNpZW5jeSwgcHVyZSB0ZWNobmljYWwgZWZmaWNpZW5jeSwgYW5kIHNjYWxlIGVmZmljaWVuY3kgYWNyb3NzIHByb3ZpbmNlcyBpbiBJbmRvbmVzaWEgMTk5MCBhbmQgMjAxMC4gUiBTdHVkaW8vUlB1YnMuIEF2YWlsYWJsZSBhdCBodHRwczovL3JwdWJzLmNvbS9xdWFyY3MtbGFiL2VmZmljaWVuY3ktY2x1c3RlcnMtaW5kb25lc2lhLTE5OTAtMjAxMAoKLSBbTWVuZGV6LUd1ZXJyYSwgQy4gKDIwMTgpLiBPbiB0aGUgZGlzdHJpYnV0aW9uIGR5bmFtaWNzIG9mIGh1bWFuIGRldmVsb3BtZW50OiBFdmlkZW5jZSBmcm9tIHRoZSBtZXRyb3BvbGl0YW4gcmVnaW9ucyBvZiBCb2xpdmlhJycuIEVjb25vbWljcyBCdWxsZXRpbiwgMzgoNCksIDI0NjctMjQ3NS5dKGh0dHA6Ly93d3cuYWNjZXNzZWNvbi5jb20vUHVicy9FQi8yMDE4L1ZvbHVtZTM4L0VCLTE4LVYzOC1JNC1QMjIzLnBkZikKCgpFTkQK